package com.egg.mall.controller.web;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.egg.common.core.constant.StringPool;
import com.egg.common.core.model.controller.WebController;
import com.egg.common.core.model.response.PageData;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.util.JsonUtil;
import com.egg.mall.entity.brand.Brand;
import com.egg.mall.entity.category.Category;
import com.egg.mall.entity.sku.Sku;
import com.egg.mall.entity.spu.Spu;
import com.egg.mall.entity.spu.SpuAttribute;
import com.egg.mall.enums.AttributeTypeEnum;
import com.egg.mall.model.request.SpuPostOrPut;
import com.egg.mall.model.request.SpuStatePut;
import com.egg.mall.model.response.web.SpuInfo;
import com.egg.mall.model.response.web.SpuPage;
import com.egg.mall.service.brand.IBrandService;
import com.egg.mall.service.category.ICategoryService;
import com.egg.mall.service.sku.ISkuService;
import com.egg.mall.service.spu.ISpuAttributeService;
import com.egg.mall.service.spu.ISpuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author east
 * @since 2022-08-08
 */
@Slf4j
@Api(tags = WebController.API_PREFIX + "商品SPU")
@RestController
@RequestMapping("/spu")
public class WebSpuController extends WebController {


    @Autowired
    private ISpuService spuService;
    @Autowired
    private ISkuService skuService;
    @Autowired
    private IBrandService brandService;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private ISpuAttributeService spuAttributeService;


    @ApiOperation(value = "SPU新增")
    @PostMapping
    public ResponseData<Long> spuPost(@RequestBody SpuPostOrPut param) {
        Long id = spuService.addSpu(param);
        return ResponseData.success(id);
    }

    @ApiOperation(value = "SPU分页")
    @GetMapping("/page")
    public ResponseData<PageData<SpuPage>> spuPageGet(
            @ApiParam(value = "页数", required = true) @RequestParam(value = "current", defaultValue = "1") Integer current
            , @ApiParam(value = "页长", required = true) @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
            , @ApiParam(value = "名称") @RequestParam(value = "name", required = false) String name
            , @ApiParam(value = "商品分类ID") @RequestParam(value = "categoryId", required = false) Long categoryId
    ) {
        LambdaQueryWrapper<Spu> qw = spuService.buildLambdaSortQw();
        if (ObjectUtil.isNotEmpty(name)) {
            qw.like(Spu::getName, name);
        }
        if (ObjectUtil.isNotEmpty(categoryId)) {
            qw.eq(Spu::getCategoryId, categoryId);
        }
        Page<Spu> dbSpu = spuService.page(new Page<>(current, pageSize), qw);
        List<Sku> dbSku = skuService.findBySpuId(dbSpu.getRecords().stream().map(o -> o.getId()).collect(Collectors.toSet()));
        List<Brand> dbBrand = brandService.baseFindById(dbSpu.getRecords().stream().map(o -> o.getBrandId()).collect(Collectors.toSet()));
        List<Category> dbCategory = categoryService.baseFindById(dbSpu.getRecords().stream().map(o -> o.getCategoryId()).collect(Collectors.toSet()));
        Map<Long, List<Sku>> skuGroup = dbSku.stream().collect(Collectors.groupingBy(o -> o.getSpuId()));
        Map<Long, String> brandMap = dbBrand.stream().collect(Collectors.toMap(o -> o.getId(), o -> o.getName()));
        Map<Long, String> categoryMap = dbCategory.stream().collect(Collectors.toMap(o -> o.getId(), o -> o.getName()));
        List<SpuPage> spuPage = new ArrayList<>();
        dbSpu.getRecords().forEach(o -> {
            SpuPage page = JsonUtil.objToObj(o, SpuPage.class);
            if (ObjectUtil.isNotEmpty(o.getAlbum())) {
                page.setAlbum(Arrays.stream(o.getAlbum().split(StringPool.COMMA)).collect(Collectors.toList()));
            }
            page.setBrandName(brandMap.getOrDefault(o.getBrandId(), ""));
            page.setCategoryName(categoryMap.getOrDefault(o.getCategoryId(), ""));
            List<Sku> sku = skuGroup.getOrDefault(o.getId(), Collections.emptyList());
            List<SpuPage.Sku> skuList = JsonUtil.listToList(sku, SpuPage.Sku.class);
            page.setSkuList(skuList);
            spuPage.add(page);
        });
        return ResponseData.success(new PageData<>(dbSpu, spuPage));
    }

    @ApiOperation(value = "SPU信息")
    @GetMapping("/{id}/info")
    public ResponseData<SpuInfo> spuInfoGet(@ApiParam(value = "SPU ID") @PathVariable Long id) {
        Spu dbSpu = spuService.baseGetById(id);
        SpuInfo info = JsonUtil.objToObj(dbSpu, SpuInfo.class);
        if (ObjectUtil.isNotEmpty(dbSpu.getAlbum())) {
            info.setSubPicUrls(Arrays.stream(dbSpu.getAlbum().split(StringPool.COMMA)).collect(Collectors.toList()));
        }
        List<SpuAttribute> dbSpuAttribute = spuAttributeService.findBySpuId(dbSpu.getId());
        List<Sku> dbSku = skuService.findBySpuId(dbSpu.getId());
        List<SpuAttribute> dbAttr = dbSpuAttribute.stream()
                .filter(o -> Objects.equals(AttributeTypeEnum.ATTR.getCode(), o.getType()))
                .collect(Collectors.toList());
        List<SpuAttribute> dbSpec = dbSpuAttribute.stream()
                .filter(o -> Objects.equals(AttributeTypeEnum.SPEC.getCode(), o.getType()))
                .collect(Collectors.toList());
        List<SpuInfo.SpuAttribute> attr = JsonUtil.listToList(dbAttr, SpuInfo.SpuAttribute.class);
        info.setAttrList(attr);
        List<SpuInfo.SpuAttribute> spec = JsonUtil.listToList(dbSpec, SpuInfo.SpuAttribute.class);
        info.setSpecList(spec);
        List<SpuInfo.Sku> skuList = JsonUtil.listToList(dbSku, SpuInfo.Sku.class);
        info.setSkuList(skuList);
        return ResponseData.success(info);
    }

    @ApiOperation(value = "SPU修改")
    @PutMapping("/{id}")
    public ResponseData<Long> spuPut(
            @ApiParam(value = "SPU ID") @PathVariable String id
            , @RequestBody SpuPostOrPut edit
    ) {
        Long existId = spuService.editSpu(id, edit);
        return ResponseData.success(existId);
    }

    @ApiOperation(value = "SPU状态修改")
    @PatchMapping("/{id}/state")
    public ResponseData<Long> spuStatePut(
            @ApiParam(value = "SPU ID") @PathVariable String id
            , @RequestBody SpuStatePut edit
    ) {
        Long existId = spuService.editSpuState(id, edit);
        return ResponseData.success(existId);
    }

    @ApiOperation(value = "SPU删除")
    @DeleteMapping
    public ResponseData<String> spuDel(
            @ApiParam(value = "ID集合", required = true) @RequestParam(value = "ids") Collection<String> ids
    ) {
        spuService.delSpu(
                ids.stream()
                        .filter(o -> ObjectUtil.isNotEmpty(o))
                        .map(o -> Long.valueOf(o))
                        .collect(Collectors.toSet())
        );
        return ResponseData.success();
    }


}

